library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity divisor is
generic (N : integer := 32);
port( A  : in  std_logic_vector (N-1 downto 0); -- dividend
		B  : in  std_logic_vector (N-1 downto 0); -- divisor
		sgn: in  std_logic;
		Rs : out std_logic_vector (N-1 downto 0); -- result
		Rm : out std_logic_vector (N-1 downto 0); -- remainder
		ovf: out std_logic
);
end divisor;

architecture behav of divisor is
signal zero : std_logic_vector (N-1 downto 0);
begin

zero <= (others => '0');
ovf  <= '1' when B = zero else '0';

p_divide: process (A,B,sgn,zero)
	variable result_u	  : unsigned(N-1 downto 0);
	variable remainder_u: unsigned(N-1 downto 0);
	variable tmp_u 	  : unsigned(N-1 downto 0);
	variable result_s	  : signed(N-1 downto 0);
	variable remainder_s: signed(N-1 downto 0);
	variable tmp_s 	  : signed(N-1 downto 0);
begin

	if sgn = '0' then
		tmp_u := unsigned(A);
		for i in N-1 downto 0 loop
			if (tmp_u(N-1 downto i) >= unsigned(B)) then
				result_u(i) := '1';
				remainder_u := unsigned(tmp_u(N-1 downto i)) - unsigned(B);
				if (i /= 0) then
					tmp_u(N-1 downto i) := remainder_u(N-1-i downto 0);
					tmp_u(i-1) := A(i-1);
				end if;
			else
				result_u(i) := '0';
				remainder_u := unsigned(zero);
				remainder_u(N-1-i downto 0) := unsigned(tmp_u(N-1 downto i));
			end if;
		end loop; 
		
		Rs <= std_logic_vector(result_u);
		Rm <= std_logic_vector(remainder_u);
	else
		tmp_s := signed(A);
		for i in N-1 downto 0 loop
			if (tmp_s(N-1 downto i) >= signed(B)) then
				result_s(i) := '1';
				remainder_s := signed(tmp_s(N-1 downto i)) - signed(B);
				if (i /= 0) then
					tmp_s(N-1 downto i) := remainder_s(N-1-i downto 0);
					tmp_s(i-1) := A(i-1);
				end if;
			else
				result_s(i) := '0';
				remainder_s := signed(zero);
				remainder_s(N-1-i downto 0) := signed(tmp_s(N-1 downto i));
			end if;
		end loop; 
		
		Rs <= std_logic_vector(result_s);
		Rm <= std_logic_vector(remainder_s);
	end if;

end process;

end behav;
